package com.caifu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caifu.bean.PageDo;
import com.caifu.bean.Result;
import com.caifu.bean.ResultUtil;
import com.caifu.controller.AbstractController;
import com.caifu.enums.LabelTypeEnum;
import com.caifu.enums.SexTypeEnum;
import com.caifu.excel.ExcelElderlyInfo;
import com.caifu.mapper.*;
import com.caifu.neums.CognitionStatusEnum;
import com.caifu.neums.CostTypeEnum;
import com.caifu.pojo.*;
import com.caifu.service.ElderlyInfoService;
import com.caifu.service.UserInfoService;
import com.caifu.util.AesMyUtil;
import com.caifu.util.CheckIdCardUtil;
import com.caifu.util.Constance;
import com.caifu.util.Util;
import com.caifu.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * ClassName : ElderlyInfoServiceImpl
 *
 * @author :  yb
 * @description ：
 * @date : 2020-11-06 16:56
 */
@Service
public class ElderlyInfoServiceImpl extends AbstractController implements ElderlyInfoService {

    @Resource
    private YlElderlyInfoMapper ylElderlyInfoMapper;
    @Resource
    private YlBuildingMapper ylBuildingMapper;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private YsLabelMapper ysLabelMapper;
    @Resource
    private YlStaffInfoMapper ylStaffInfoMapper;
    @Resource
    private YlCostMapper ylCostMapper;
    @Resource
    private YlFloorMapper ylFloorMapper;
    @Resource
    private YlRoomMapper ylRoomMapper;
    @Resource
    private YlBedMapper ylBedMapper;
    @Resource
    private YlContractInfoMapper ylContractInfoMapper;
    @Resource
    private YlNursingRecordMapper ylNursingRecordMapper;
    @Resource
    private YlAssessmentRecordMapper ylAssessmentRecordMapper;
    @Resource
    private YlBedRecordMapper ylBedRecordMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private YlElderlyBillMapper ylElderlyBillMapper;


    /**
     * 获取现住老人-列表
     *
     * @param vo vo
     * @return Result
     */
    @Override
    public Result<Object> getElderlyInfoPageList(ElderlyInfoVO vo) {
        Map<String, Object> params = new HashMap<>(10);
        int start = (vo.getCurrentPage() - 1) * vo.getPageSize();
        int end = vo.getPageSize();
        params.put("start", start);
        params.put("end", end);
        //设置查询条件
        setParamForQueryElderlyInfo(params, vo);
        //查询列表 和 总数
        List<Map<String, Object>> resultList = ylElderlyInfoMapper.getElderlyInfoPageList(params);
        Integer totalCount = ylElderlyInfoMapper.getElderlyInfoPageListTotalCount(params);
        return ResultUtil.getPageDataSuccess(new PageDo<>(vo.getCurrentPage(), vo.getPageSize(), totalCount, resultList));
    }

    /**
     * 获取 敬老院入住老人明细表 数据
     *
     * @param vo vo
     * @return List
     */
    @Override
    public List<ExcelElderlyInfo> getElderlyInfoReportData(ElderlyInfoVO vo) {
        Map<String, Object> params = new HashMap<>(10);
        //设置查询条件
        setParamForQueryElderlyInfo(params, vo);
        //查询列表 和 总数
        List<Map<String, Object>> elderlyInfoList = ylElderlyInfoMapper.getElderlyInfoPageList(params);

        //返回的list
        List<ExcelElderlyInfo> resultList = new ArrayList<>();

        elderlyInfoList.forEach(map -> {
            ExcelElderlyInfo info = Util.mapToEntity(map, ExcelElderlyInfo.class);

            //身份证
            if (Util.isNotNull(info.getUserPid())) {
                try {
                    info.setUserPid(AesMyUtil.Decrypt(info.getUserPid()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //联系电话
            if (Util.isNotNull(info.getInfoContactMobile())) {
                List<String> list = Arrays.asList(info.getInfoContactMobile().split(","));
                List<String> mobileList = new ArrayList<>();
                list.forEach(mobile -> {
                    try {
                        mobileList.add(AesMyUtil.Decrypt(mobile));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
                info.setInfoContactMobile(String.join(",", mobileList));
            }
            //文化程度
            if (Util.isNotNull(info.getEducation())) {
                info.setEducation(getYsLabelByLabelCode(info.getEducation()).getLabelName());
            }
            //认知  认知情况 0：否 1：是
            if (Util.isNotNull(info.getCognitionStatus())) {
                info.setCognitionStatus(CognitionStatusEnum.getName(info.getCognitionStatus()));
            }
            //社保类型
            if (Util.isNotNull(info.getSocialSecurityType())) {
                info.setSocialSecurityType(getYsLabelByLabelCode(info.getSocialSecurityType()).getLabelName());
            }
            resultList.add(info);
        });

        return resultList;
    }


    /**
     * 获取 label
     *
     * @param labelCode labelCode
     * @return YsLabel
     */
    private YsLabel getYsLabelByLabelCode(String labelCode) {
        QueryWrapper<YsLabel> labelQueryWrapper = new QueryWrapper<>();
        if (Util.isNotNull(labelCode)) {
            labelQueryWrapper.eq("LABEL_CODE", labelCode);
            labelQueryWrapper.eq("STATUS", "1");
        }
        return ysLabelMapper.selectOne(labelQueryWrapper);
    }


    /**
     * 设置 查询条件
     */
    private void setParamForQueryElderlyInfo(Map<String, Object> params, ElderlyInfoVO vo) {
        //房间号
        if (Util.isNotNull(vo.getRoomName())) {
            params.put("roomName", vo.getRoomName());
        }
        //楼苑
        if (Util.isNotNull(vo.getBuildingNo())) {
            params.put("buildingNo", vo.getBuildingNo());
        }
        //床号
        if (Util.isNotNull(vo.getBedName())) {
            params.put("bedName", vo.getBedName());
        }
        //楼层
        if (Util.isNotNull(vo.getFloorNo())) {
            params.put("floorNo", vo.getFloorNo());
        }
        //姓名
        if (Util.isNotNull(vo.getUserName())) {
            params.put("userName", "%" + vo.getUserName() + "%");
        }
        //护理评估有效时间
        if (Util.isNotNull(vo.getNextEffectDate())) {
            params.put("nextEffectDate", transformDate(vo.getNextEffectDate()));
        }
        //评估有效时间
        if (Util.isNotNull(vo.getValidDate())) {
            params.put("validDate", transformDate(vo.getValidDate()));
        }
        //护理员
        if (Util.isNotNull(vo.getStaffNo())) {
            params.put("staffNo", vo.getStaffNo());
        }
        //入住时间
        if (Util.isNotNull(vo.getStartDate())) {
            params.put("startDate", transformDate(vo.getStartDate()));
        }
        //合同截止时间
        if (Util.isNotNull(vo.getEndDate())) {
            params.put("endDate", transformDate(vo.getEndDate()));
        }
        //性别
        if (Util.isNotNull(vo.getUserSex())) {
            params.put("userSex", vo.getUserSex());
        }
        //护理等级
        if (Util.isNotNull(vo.getNursingCostNo())) {
            params.put("nursingCostNo", vo.getNursingCostNo());
        }
        //评估等级
        if (Util.isNotNull(vo.getAssessmentCostNo())) {
            params.put("assessmentCostNo", vo.getAssessmentCostNo());
        }
        //认知
        if (Util.isNotNull(vo.getCognitionStatus())) {
            params.put("cognitionStatus", vo.getCognitionStatus());
        }
        //排序  1-默认值=‘全部’  2-费用由高到低  3-费用从低到高
        if (Util.isNotNull(vo.getSort())) {
            params.put("sort", vo.getSort());
        }
        //年龄范围 //1-60岁以下  2- 60-69岁 3 - 70-79岁 4-80-89  5-90-99岁 6-100岁及以上
        if (Util.isNotNull(vo.getAge())) {
            params.put("age", vo.getAge());
        }
        if (Util.isNotNull(vo.getIsStayBack())) {
            params.put("isStayBack", vo.getIsStayBack());
        }
        //养老院编号
        if (Util.isNotNull(vo.getPensionNo())) {
            params.put("pensionNo", vo.getPensionNo());
        }
        if (Util.isNotNull(vo.getUserState())) {
            params.put("userState", vo.getUserState());
        }
    }

    /**
     * yyyy-MM-dd 转成 yyyyMMdd
     *
     * @param date date
     * @return String
     */
    private String transformDate(String date) {
        return date.replace("-", "");
    }


    /**
     * yyyyMMdd 转 yyyy-MM-dd
     *
     * @param date date
     * @return String
     */
    private String transformLocalTimeFormat(String date) {
        if (Util.isNull(date)) {
            return "";
        }

        return LocalDate.parse(date, DateTimeFormatter.BASIC_ISO_DATE).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    /**
     * 验证新增老人  身份证号是否存在
     *
     * @param userPid userPid
     * @return Result
     */
    @Override
    public Result<Object> isExistForUserPid(String userPid) throws Exception {

        YlElderlyInfo elderlyInfo = getYlElderlyInfoByUserPid(userPid);
        if (Util.isNull(elderlyInfo)) {
            return ResultUtil.success();
        } else {
            return ResultUtil.errorMsg("身份证信息重复,请重新输入");
        }
    }

    /**
     * 通过身份证验证 是否已存在
     *
     * @param userPid userPid
     * @return YlElderlyInfo
     * @throws Exception Exception
     */
    private YlElderlyInfo getYlElderlyInfoByUserPid(String userPid) throws Exception {
        QueryWrapper<YlElderlyInfo> ylElderlyInfoWrapper = new QueryWrapper<>();
        ylElderlyInfoWrapper.eq("user_pid", AesMyUtil.Encrypt(userPid));
        ylElderlyInfoWrapper.eq("USER_STATE", "1");
        return ylElderlyInfoMapper.selectOne(ylElderlyInfoWrapper);
    }

    /**
     * 获取添加老人页面需要的一些数据
     *
     * @return Map
     */
    @Override
    public Map<String, Object> getAddPageOfElderlyInfoData() {
        Map<String, Object> result = new HashMap<>(10);
        //民族
        result.put("nationList", getYsLabelListByParentCode(LabelTypeEnum.MZ.getKey()));
        //户籍
        result.put("householdRegisterList", getYsLabelListByParentCode(LabelTypeEnum.HJ.getKey()));
        //社保类型
        result.put("socialSecurityTypeList", getYsLabelListByParentCode(LabelTypeEnum.SBLX.getKey()));
        //文化程度
        result.put("educationList", getYsLabelListByParentCode(LabelTypeEnum.WHCD.getKey()));
        //床位费标准
        result.put("bedFeeTypeList", getYlCostByCostType(CostTypeEnum.CWF.getKey()));
        //护理等级
        result.put("nursingCostList", getYlCostByCostType(CostTypeEnum.HLF.getKey()));
        //评估等级
        result.put("assessmentCostList", getYlCostByCostType(CostTypeEnum.CHXF.getKey()));


        return result;
    }


    /**
     * 获取 费用表信息
     *
     * @param costType costType
     * @return List
     */
    private List<YlCost> getYlCostByCostType(String costType) {
        QueryWrapper<YlCost> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("STATUS", "1");
        queryWrapper.eq("COST_TYPE", costType);
        return ylCostMapper.selectList(queryWrapper);
    }


    /**
     * 获取护理人员
     *
     * @return List
     */
    @Override
    public Result<Object> getYlStaffInfoList(YlStaffInfoVo vo) {

        QueryWrapper<YlStaffInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PENSION_NO", vo.getCurrentPensionNo());
        queryWrapper.eq("STAFF_STATE", "1");
        if (Util.isNotNull(vo.getStaffName())) {
            queryWrapper.like("STAFF_NAME", vo.getStaffName());
        }
        if (Util.isNotNull(vo.getPensionNo())) {
            queryWrapper.eq("PENSION_NO", vo.getPensionNo());
        }

        IPage<YlStaffInfo> staffInfoPage = ylStaffInfoMapper.selectPage(new Page<>(vo.getCurrentPage(), vo.getPageSize()), queryWrapper);
        return ResultUtil.getPageDataSuccess(new PageDo<>(vo.getCurrentPage(), vo.getPageSize(), Integer.parseInt(staffInfoPage.getTotal() + ""), staffInfoPage.getRecords()));

    }


    @Override
    public List<YsLabel> getYsLabelListByParentCode(String parentCode) {
        QueryWrapper<YsLabel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "1");
        queryWrapper.eq("parent_code", parentCode);
        return ysLabelMapper.selectList(queryWrapper);
    }


    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Object> saveYlElderlyInfo(ElderlyInfoAddVO vo) throws Exception {

        YlElderlyInfo isExist = getYlElderlyInfoByUserPid(vo.getUserPid());
        if (Util.isNotNull(isExist)) {
            return ResultUtil.errorMsg("该身份证老人信息已存在");
        }

        //----------保存-养老院老人信息-------
        YlElderlyInfo info = new YlElderlyInfo();
        BeanUtils.copyProperties(vo, info);
        info.setUserNo(Constance.getStringRandom(20));
        //证件号
        if (Util.isNotNull(info.getUserPid())) {
            //计算年龄
            info.setAge(CheckIdCardUtil.getAgeByCertId(info.getUserPid()));
            //出生日期
            info.setBirthDate(info.getUserPid().substring(6, 14));
            //加密身份证号
            info.setUserPid(AesMyUtil.Encrypt(info.getUserPid()));
        }
        //缴纳时间  时间格式化
        if (Util.isNotNull(info.getPaymentDate())) {
            info.setPaymentDate(formatDateForSaveOrUpdate(info.getPaymentDate()));
        }

        //是否退住 1-否 2-是
        info.setIsStayBack(1);
        //1正常 9：删除
        info.setUserState("1");
        info.setCreateDate(new Date());
        //是否需要通知长护险评估 1-通知 2-不通知
        info.setIsNotice("2");
        //是否长已创建健康档案 0：未建档 1：已建档
        info.setIsArchive("0");
        //保存老人信息
        ylElderlyInfoMapper.insert(info);
        //保存 紧急联系人
        List<UserInfoContact> userInfoContactList = info.getUserInfoContactList();
        if (Util.isNotNull(userInfoContactList) && userInfoContactList.size() > 0) {
            userInfoService.saveUserInfoContact(info.getUserNo(), userInfoContactList);
        }

        //如果该老人信息存在于老人档案，需要回写给老人档案两个字段信息：养老院名称和入住时间
        UserInfo userInfo = userInfoService.getUserInfoWithUserPid(vo.getUserPid());
        if (Util.isNotNull(userInfo)) {
            userInfo.setPensionInstitutions(vo.getPensionNo());
            userInfo.setCheckInTime(formatDateForSaveOrUpdate(info.getYlContractInfo().getStartDate()));
            userInfoMapper.updateById(userInfo);
        }


        //  给做账的时候插一条记录   ----- yl_elderly_bill
        YlElderlyBill ylElderlyBill = new YlElderlyBill();
        ylElderlyBill.setUserNo(info.getUserNo());
        ylElderlyBill.setBillBalance(0.00);
        ylElderlyBill.setTotalMonthFee(0.00);
        ylElderlyBill.setTotalPayFee(0.00);
        ylElderlyBill.setTotalRealpayFee(0.00);
        ylElderlyBill.setBillState("0");
        ylElderlyBill.setState("1");
        ylElderlyBillMapper.insert(ylElderlyBill);


        //========各种合同存放================
        //--入驻合同--
        YlContractInfo contractInfo = info.getYlContractInfo();
        contractInfo.setOperationRecord(getUser().getUserName() + " 创建入住信息为 【" + contractInfo.getStartDate() + "~" + contractInfo.getEndDate() + "】");
        //转换数据
        transformYlContractInfo(info.getYlContractInfo());
        contractInfo.setUserNo(info.getUserNo());
        contractInfo.setTellerNo(info.getTellerNo());
        contractInfo.setCreateTime(new Date());
        //是否有效 1-有效 2无效
        contractInfo.setIsEffective("1");
        ylContractInfoMapper.insert(contractInfo);

        //--护理等级--
        YlNursingRecord nursingRecord = info.getYlNursingRecord();
        //转换数据
        transformYlNursingRecord(nursingRecord);
        //是否有效 1-有效 2-无效
        nursingRecord.setIsEffective("1");
        nursingRecord.setCreateTime(new Date());
        nursingRecord.setTellerNo(info.getTellerNo());
        nursingRecord.setUserNo(info.getUserNo());
        nursingRecord.setOperationRecord(getUser().getUserName() + " 创建 护理信息为 " + getNursingOperationStr(nursingRecord));
        ylNursingRecordMapper.insert(nursingRecord);

        //--评估等级--
        YlAssessmentRecord assessmentRecord = info.getYlAssessmentRecord();
        //转换数据
        transformYlAssessmentRecord(assessmentRecord);
        assessmentRecord.setCreateTime(new Date());
        assessmentRecord.setIsEffective("1");
        assessmentRecord.setTellerNo(info.getTellerNo());
        assessmentRecord.setUserNo(info.getUserNo());
        assessmentRecord.setEffectDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        assessmentRecord.setOperationRecord(getUser().getUserName() + " 创建 评估信息为" + getAssessmentOperationStr(assessmentRecord));
        //类型 1-基础数据 2-健康档案
        assessmentRecord.setRecordType("1");
        ylAssessmentRecordMapper.insert(assessmentRecord);

        //存放床位  注意改成已使用状态
        YlBedRecord bedRecord = info.getYlBedRecord();
        bedRecord.setCreateTime(new Date());
        bedRecord.setEffectDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        bedRecord.setTellerNo(info.getTellerNo());
        bedRecord.setIsEffective("1");
        bedRecord.setPensionNo(info.getPensionNo());
        bedRecord.setUserNo(info.getUserNo());
        bedRecord.setOperationRecord(getUser().getUserName() + " 创建 床位信息为 " + getBedRecordOperationStr(bedRecord));
        ylBedRecordMapper.insert(bedRecord);
        //设置成已使用的床
        setBedNoForBedEmpty(bedRecord.getBedNo(), "1");


        return ResultUtil.success();
    }

    /**
     * 设置空置的床
     */
    private void setBedNoForBedEmpty(String bedNo, String bedEmptyType) {
        if (Util.isNull(bedNo)) {
            return;
        }
        YlBed bed = getYlBedByBedNo(bedNo);
        //床位是否为空 0：空置 1：已使用 2：预定
        bed.setBedEmpty(bedEmptyType);
        ylBedMapper.updateById(bed);
    }

    /**
     * 护理等级的操作str
     *
     * @param nursingRecord nursingRecord
     * @return String
     */
    private String getNursingOperationStr(YlNursingRecord nursingRecord) {
        String staffName = getStaffInfo(nursingRecord.getStaffNo()).getStaffName();
        String costName = getYlCostByCostNo(nursingRecord.getCostNo()).getCostName();
        return "【" + costName + " ~ " + transformLocalTimeFormat(nursingRecord.getEffectDate()) + "~" + staffName + "】";
    }

    /**
     * 获得长护险的操作str
     *
     * @return String
     */
    private String getAssessmentOperationStr(YlAssessmentRecord assessmentRecord) {
        String costName = getYlCostByCostNo(assessmentRecord.getCostNo()).getCostName();
        return "【" + costName + " ~ " + transformLocalTimeFormat(assessmentRecord.getValidDate()) + "】";
    }

    /**
     * 获得 床位 的操作str
     *
     * @param bedRecord bedRecord
     * @return String
     */
    private String getBedRecordOperationStr(YlBedRecord bedRecord) {
        YlCost cost = getYlCostByCostNo(bedRecord.getBedFeeType());
        String price = Util.isNull(cost) ? "0" : cost.getCostPrice().toString();

        String buildingFloorRoomBedStr = getBuildingFloorRoomBedStr(bedRecord.getBuildingNo(), bedRecord.getFloorNo(), bedRecord.getRoomNo(), bedRecord.getBedNo());
        return "【" + buildingFloorRoomBedStr + "~" + price + " ~ " + transformLocalTimeFormat(bedRecord.getEffectDate()) + "】";
    }


    /**
     * 删除老人
     *
     * @param userNo userNo
     * @return Result
     */
    @Override
    public Result<Object> deleteYlElderlyInfo(String userNo) {
        YlElderlyInfo elderlyInfo = ylElderlyInfoMapper.selectById(userNo);
        elderlyInfo.setUserState("9");
        ylElderlyInfoMapper.updateById(elderlyInfo);

        YlBedRecord bedRecord = getYlBedByUserNo(elderlyInfo.getUserNo());
        //床位置空
        setBedNoForBedEmpty(bedRecord.getBedNo(), "0");
        return ResultUtil.success();
    }

    /**
     * 获取有效的一条床位记录  根据userNo
     *
     * @param userNo userNo
     * @return YlBed
     */
    private YlBedRecord getYlBedByUserNo(String userNo) {
        QueryWrapper<YlBedRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_effective", "1");
        queryWrapper.eq("USER_NO", userNo);
        return ylBedRecordMapper.selectOne(queryWrapper);
    }


    /**
     * 获取床位
     *
     * @param bedNo bedNo
     * @return YlBed
     */
    private YlBed getYlBedByBedNo(String bedNo) {
        return ylBedMapper.selectById(bedNo);
    }

    /**
     * 转换合同 部分字段
     *
     * @param contractInfo contractInfo
     */
    private void transformYlContractInfo(YlContractInfo contractInfo) {
        //合同入驻时间
        if (Util.isNotNull(contractInfo.getStartDate())) {
            contractInfo.setStartDate(formatDateForSaveOrUpdate(contractInfo.getStartDate()));
        }
        //合同截至时间
        if (Util.isNotNull(contractInfo.getEndDate())) {
            contractInfo.setEndDate(formatDateForSaveOrUpdate(contractInfo.getEndDate()));
        }
    }

    /**
     * 转换 护理等级 部分字段
     *
     * @param nursingRecord nursingRecord
     */
    private void transformYlNursingRecord(YlNursingRecord nursingRecord) {
        //评估生效期
        if (Util.isNotNull(nursingRecord.getEffectDate())) {
            //下次评估生效期(护理评估生效日期一年后)
            nursingRecord.setNextEffectDate(LocalDate.parse(nursingRecord.getEffectDate()).plusYears(1).format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            nursingRecord.setEffectDate(formatDateForSaveOrUpdate(nursingRecord.getEffectDate()));
        }
    }

    /**
     * 转换 评估等级 部分字段
     *
     * @param assessmentRecord assessmentRecord
     */
    private void transformYlAssessmentRecord(YlAssessmentRecord assessmentRecord) {
        if (Util.isNotNull(assessmentRecord.getValidDate())) {
            assessmentRecord.setValidDate(formatDateForSaveOrUpdate(assessmentRecord.getValidDate()));
        }
        if (Util.isNotNull(assessmentRecord.getEffectDate())) {
            assessmentRecord.setEffectDate(formatDateForSaveOrUpdate(assessmentRecord.getEffectDate()));
        }
    }

    /**
     * 格式化时间  yyyy-MM-dd -> yyyyMMdd
     */
    private String formatDateForSaveOrUpdate(String date) {
        return date.replace("-", "");
    }

    /**
     * 获取当前养老院的楼苑列表
     *
     * @param pensionNo pensionNo 养老机构编号
     * @return List
     */
    @Override
    public List<YlBuilding> getBuildingListByPensionNo(String pensionNo) {
        QueryWrapper<YlBuilding> buildingQueryWrapper = new QueryWrapper<>();
        buildingQueryWrapper.eq("PENSION_NO", pensionNo);
        buildingQueryWrapper.eq("BUILDING_STATE", "1");
        return ylBuildingMapper.selectList(buildingQueryWrapper);
    }


    /**
     * 获取楼层信息
     *
     * @param buildingNo buildingNo
     * @return Result
     */
    @Override
    public Result<Object> getFloorByBuildingNo(String buildingNo) {
        QueryWrapper<YlFloor> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("BUILDING_NO", buildingNo);
        queryWrapper.eq("FLOOR_STATE", "1");
        return ResultUtil.getDataSuccess(ylFloorMapper.selectList(queryWrapper));
    }

    /**
     * 获取房屋信息
     *
     * @param floorNo floorNo
     * @return Result
     */
    @Override
    public Result<Object> getRoomByFloorNo(String floorNo) {
        QueryWrapper<YlRoom> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("FLOOR_NO", floorNo);
        queryWrapper.eq("ROOM_STATE", "1");
        //房间类型 101:空置 102：其他
        queryWrapper.eq("ROOM_TYPE", "101");
        return ResultUtil.getDataSuccess(ylRoomMapper.selectList(queryWrapper));
    }

    /**
     * 获取床位信息
     *
     * @param roomNo roomNo
     * @return Result
     */
    @Override
    public Result<Object> getBedByRoomNo(String roomNo) {
        QueryWrapper<YlBed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ROOM_NO", roomNo);
        queryWrapper.eq("BED_STATE", "1");
        //床位是否为空 0：空置 1：已使用 2预定
        queryWrapper.eq("BED_EMPTY", "0");

        return ResultUtil.getDataSuccess(ylBedMapper.selectList(queryWrapper));
    }

    /**
     * 查看老人 获取数据
     *
     * @param userNo userNo
     * @return Map
     * @throws Exception Exception
     */
    @Override
    public Map<String, Object> getElderlyInfoDetailByUserNo(String userNo) throws Exception {
        Map<String, Object> resultMap = new HashMap<>(10);

        YlElderlyInfo elderlyInfo = ylElderlyInfoMapper.selectById(userNo);
        //转换数据
        transformElderlyInfoForDetail(elderlyInfo);
        //获取联系人
        List<UserInfoContact> userInfoContactList = userInfoService.getUserInfoContactByUserNo(userNo);
        elderlyInfo.setUserInfoContactList(userInfoContactList);

        //合同截止时间  和开始时间
        List<YlContractInfo> contractInfoList = getContractInfoByUserNo(userNo);
        String endDate = contractInfoList.size() > 0 ? contractInfoList.get(0).getEndDate() : "";
        String startDate = contractInfoList.size() > 0 ? contractInfoList.get(0).getStartDate() : "";
        resultMap.put("endDate", transformDateForDetail(endDate));
        resultMap.put("startDate", transformDateForDetail(startDate));

        //老人信息
        resultMap.put("elderlyInfo", elderlyInfo);

        //*********护理等级信息**********/
        YlNursingRecord nursingRecord = getNursingRecordByUserNo(userNo);
        //下次护理评估时间
        resultMap.put("nextEffectDate", transformDateForDetail(nursingRecord.getNextEffectDate()));
        //护理等级No
        resultMap.put("nursingCostNo", getYlCostByCostNo(nursingRecord.getCostNo()).getCostNo());
        //护理等级
        resultMap.put("nursingCostName", getYlCostByCostNo(nursingRecord.getCostNo()).getCostName());
        //护理护理评估生效日期
        resultMap.put("nursingEffectDate", transformDateForDetail(nursingRecord.getEffectDate()));
        YlStaffInfo staffInfo = getStaffInfo(nursingRecord.getStaffNo());
        //护理人员名称
        resultMap.put("staffName", Util.isNull(staffInfo) ? "" : staffInfo.getStaffName());

        //*********长护险等级信息**********/
        YlAssessmentRecord assessmentRecord = getAssessmentRecordByUserNo(userNo);
        //长护险评估等级
        resultMap.put("assessmentCostName", getYlCostByCostNo(assessmentRecord.getCostNo()).getCostName());
        //评估有效期
        resultMap.put("validDate", transformDateForDetail(assessmentRecord.getValidDate()));

        //床位信息：楼苑/房间号/床位
        Map<String, Object> buildingRoomBed = ylElderlyInfoMapper.getBuildingInfoByUserNo(userNo);
        resultMap.put("buildingInfo", buildingRoomBed.get("buildingInfo"));
        // 养老院 - 床位信息
        resultMap.put("buildingRoomBedInfo", buildingRoomBed);

        return resultMap;
    }


    /**
     * yyyyMMdd -> yyyy-MM-dd
     *
     * @param date date
     * @return String
     */
    private String transformDateForDetail(String date) {
        if (Util.isNull(date)) {
            return "";
        }
        return LocalDate.parse(date, DateTimeFormatter.BASIC_ISO_DATE).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    /**
     * 获取老人信息
     *
     * @param userNo userNo
     * @return YlElderlyInfo
     * @throws Exception Exception
     */
    @Override
    public YlElderlyInfo getElderlyInfoByUserNo(String userNo) throws Exception {
        YlElderlyInfo elderlyInfo = ylElderlyInfoMapper.selectById(userNo);
        if (Util.isNotNull(elderlyInfo.getUserPid())) {
            elderlyInfo.setUserPid(AesMyUtil.Decrypt(elderlyInfo.getUserPid()));
        }
        //获取联系人
        List<UserInfoContact> userInfoContactList = userInfoService.getUserInfoContactByUserNo(userNo);
        elderlyInfo.setUserInfoContactList(userInfoContactList);

        return elderlyInfo;
    }

    /**
     * 通过userNo 修改老人信息
     *
     * @param vo elderlyInfoAddVO
     * @return Result
     */
    @Override
    public Result<Object> updateYlElderlyInfoByUserNo(ElderlyInfoUpdateVO vo) throws Exception {

        //----------修改-养老院老人信息-------
        YlElderlyInfo info = ylElderlyInfoMapper.selectById(vo.getUserNo());

        BeanUtils.copyProperties(vo, info);
        //证件号
        if (Util.isNotNull(info.getUserPid())) {
            //计算年龄
            info.setAge(CheckIdCardUtil.getAgeByCertId(info.getUserPid()));
            //出生日期
            info.setBirthDate(info.getUserPid().substring(6, 14));
            //加密身份证号
            info.setUserPid(AesMyUtil.Encrypt(info.getUserPid()));
        }

        //修改老人信息
        ylElderlyInfoMapper.updateById(info);

        //保存 紧急联系人
        if (Util.isNotNull(info.getUserInfoContactList()) && info.getUserInfoContactList().size() > 0) {
            userInfoService.saveUserInfoContact(info.getUserNo(), info.getUserInfoContactList());
        }

        return ResultUtil.success();
    }


    /**
     * 转换 成页面 数据
     *
     * @param elderlyInfo elderlyInfo
     * @throws Exception Exception
     */
    private void transformElderlyInfoForDetail(YlElderlyInfo elderlyInfo) throws Exception {
        //身份证
        if (Util.isNotNull(elderlyInfo.getUserPid())) {
            elderlyInfo.setUserPid(AesMyUtil.Decrypt(elderlyInfo.getUserPid()));
        }
        //教育程度
        if (Util.isNotNull(elderlyInfo.getEducation())) {
            elderlyInfo.setEducation(getYsLabelByLabelCode(elderlyInfo.getEducation()).getLabelName());
        }
        //民族
        if (Util.isNotNull(elderlyInfo.getNation())) {
            elderlyInfo.setNation(getYsLabelByLabelCode(elderlyInfo.getNation()).getLabelName());
        }
        //户籍类型
        if (Util.isNotNull(elderlyInfo.getHouseholdRegister())) {
            elderlyInfo.setHouseholdRegister(getYsLabelByLabelCode(elderlyInfo.getHouseholdRegister()).getLabelName());
        }
        //社保类型
        if (Util.isNotNull(elderlyInfo.getSocialSecurityType())) {
            elderlyInfo.setSocialSecurityType(getYsLabelByLabelCode(elderlyInfo.getSocialSecurityType()).getLabelName());
        }
        //认知
        if (Util.isNotNull(elderlyInfo.getCognitionStatus())) {
            elderlyInfo.setCognitionStatus(CognitionStatusEnum.getName(elderlyInfo.getCognitionStatus()));
        }
        //性别
        if (Util.isNotNull(elderlyInfo.getUserSex())) {
            elderlyInfo.setUserSex(SexTypeEnum.getName(elderlyInfo.getUserSex()));
        }
        //缴费日期
        if (Util.isNotNull(elderlyInfo.getPaymentDate())) {
            elderlyInfo.setPaymentDate(transformDateForDetail(elderlyInfo.getPaymentDate()));
        }
        //退住时间
        if (Util.isNotNull(elderlyInfo.getStayBackDate())) {
            elderlyInfo.setStayBackDate(transformDateForDetail(elderlyInfo.getStayBackDate()));
        }
        //死亡时间
        if (Util.isNotNull(elderlyInfo.getDeathDate())) {
            elderlyInfo.setDeathDate(transformDateForDetail(elderlyInfo.getDeathDate()));
        }

    }

    /**
     * 获取 合同 集合
     *
     * @param userNo userNo
     * @return List
     */
    private List<YlContractInfo> getContractInfoByUserNo(String userNo) {
        QueryWrapper<YlContractInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByDesc("CREATE_TIME");

        return ylContractInfoMapper.selectList(queryWrapper);
    }

    /**
     * 获取护理信息
     *
     * @param userNo userNo
     * @return YlNursingRecord
     */
    private YlNursingRecord getNursingRecordByUserNo(String userNo) {
        QueryWrapper<YlNursingRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", "1");
        return ylNursingRecordMapper.selectOne(queryWrapper);
    }

    /**
     * 获取护理人员信息
     *
     * @param staffNo staffNo
     * @return YlStaffInfo
     */
    private YlStaffInfo getStaffInfo(String staffNo) {
        QueryWrapper<YlStaffInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("STAFF_NO", staffNo);
        queryWrapper.eq("STAFF_STATE", "1");
        return ylStaffInfoMapper.selectOne(queryWrapper);
    }


    /**
     * 获取评估信息
     *
     * @param userNo userNo
     * @return YlAssessmentRecord
     */
    private YlAssessmentRecord getAssessmentRecordByUserNo(String userNo) {
        QueryWrapper<YlAssessmentRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", "1");
        return ylAssessmentRecordMapper.selectOne(queryWrapper);
    }

    /**
     * 获取费用 数据
     *
     * @param costNo costNo
     * @return YlCost
     */
    private YlCost getYlCostByCostNo(String costNo) {
        QueryWrapper<YlCost> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("COST_NO", costNo);
        queryWrapper.eq("STATUS", "1");
        return ylCostMapper.selectOne(queryWrapper);
    }


    /**
     * 获取护理记录
     *
     * @param userNo userNo
     * @return YlNursingRecord
     */
    private YlNursingRecord getYlNursingRecord(String userNo) {
        QueryWrapper<YlNursingRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", "1");
        return ylNursingRecordMapper.selectOne(queryWrapper);

    }

    /**
     * 获得长护险 记录
     *
     * @param userNo userNo
     * @return YlAssessmentRecord
     */
    private YlAssessmentRecord getYlAssessmentRecord(String userNo) {
        QueryWrapper<YlAssessmentRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", "1");
        return ylAssessmentRecordMapper.selectOne(queryWrapper);
    }


    /**
     * 获取楼苑
     *
     * @param buildingNo buildingNo
     * @return YlBuilding
     */
    private YlBuilding getYlBuilding(String buildingNo) {
        return ylBuildingMapper.selectById(buildingNo);
    }

    /**
     * 获取楼层
     *
     * @param floorNo floorNo
     * @return YlFloor
     */
    private YlFloor getYlFloor(String floorNo) {
        return ylFloorMapper.selectById(floorNo);
    }

    /**
     * 获取房间号
     *
     * @param roomNo roomNo
     * @return YlRoom
     */
    private YlRoom getYlRoom(String roomNo) {
        return ylRoomMapper.selectById(roomNo);
    }

    /**
     * 获取床位号
     *
     * @param bedNo bedNo
     * @return YlBed
     */
    private YlBed getYlBed(String bedNo) {
        return ylBedMapper.selectById(bedNo);
    }

    /**
     * 楼苑名称+楼层名称+房屋名称+床位名称
     *
     * @param buildingNo buildingNo
     * @param floorNo    floorNo
     * @param roomNo     roomNo
     * @param bedNo      bedNo
     * @return 楼苑名称+楼层名称+房屋名称+床位名称
     */
    private String getBuildingFloorRoomBedStr(String buildingNo, String floorNo, String roomNo, String bedNo) {
        String buildingName = getYlBuilding(buildingNo).getBuildingName();
        String floorName = getYlFloor(floorNo).getFloorName();
        String roomName = getYlRoom(roomNo).getRoomName();
        String bedName = getYlBed(bedNo).getBedName() + "";
        return buildingName + "-" + floorName + "-" + roomName + "-" + bedName;
    }


    /**
     * 修改老人费用信息
     *
     * @param ylElderlyInfo ylElderlyInfo
     * @return Result
     */
    @Override
    public Result<Object> updateYlElderlyInfoFee(YlElderlyInfo ylElderlyInfo) {
        if (Util.isNull(ylElderlyInfo.getUserNo())) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }
        YlElderlyInfo info = ylElderlyInfoMapper.selectById(ylElderlyInfo.getUserNo());
        if (Util.isNull(info)) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }
        //收费情况
        if (Util.isNotNull(ylElderlyInfo.getCostFee())) {
            info.setCostFee(ylElderlyInfo.getCostFee());
        }
        //入住保证金
        if (Util.isNotNull(ylElderlyInfo.getInDeposit())) {
            info.setInDeposit(ylElderlyInfo.getInDeposit());
        }
        //缴纳时间
        if (Util.isNotNull(ylElderlyInfo.getPaymentDate())) {
            info.setPaymentDate(transformDate(ylElderlyInfo.getPaymentDate()));
        }

        ylElderlyInfoMapper.updateById(info);

        return ResultUtil.success();
    }

    /**
     * 修改 老人 入驻合同
     *
     * @param vo vo
     * @return Result
     */
    @Override
    public Result<Object> updateYlElderlyInfoContract(ElderlyInfoUpdateContractVO vo) {
        if (Util.isNull(vo.getUserNo())) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }
        //将其他合同改成无效
        updateContractInfoEffective(vo.getUserNo());

        YlContractInfo contractInfo = new YlContractInfo();
        contractInfo.setStartDate(transformDate(vo.getStartDate()));
        contractInfo.setEndDate(transformDate(vo.getEndDate()));
        contractInfo.setTellerNo(vo.getTellerNo());
        contractInfo.setUserNo(vo.getUserNo());
        contractInfo.setCreateTime(new Date());
        contractInfo.setIsEffective("1");
        contractInfo.setOperationRecord(getUser().getUserName() + " 修改入住信息为 【" + vo.getStartDate() + "~" + vo.getEndDate() + "】");
        ylContractInfoMapper.insert(contractInfo);

        return ResultUtil.success();
    }


    public void updateContractInfoEffective(String userNo) {
        List<YlContractInfo> contractInfoList = getContractInfoByUserNo(userNo);
        // 其他的改成无效  是否有效 1-有效 2无效
        contractInfoList.forEach(model -> {
            model.setIsEffective("2");
            ylContractInfoMapper.updateById(model);
        });
    }


    /**
     * 修改 老人 入驻合同----续签合同
     *
     * @param vo vo
     * @return Result
     */
    @Override
    public Result<Object> updateYlElderlyInfoContractOfRenewal(ElderlyInfoUpdateContractVO vo) {
        if (Util.isNull(vo.getUserNo())) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }
        List<YlContractInfo> contractInfoList = getContractInfoByUserNo(vo.getUserNo());
        //获取上一份合同的开始时间
        if (Util.isNull(contractInfoList) || contractInfoList.size() <= 0) {
            return ResultUtil.errorMsg("此用户入驻合同有误");
        }

        String startDate = contractInfoList.get(0).getStartDate();
        YlContractInfo contractInfo = new YlContractInfo();
        contractInfo.setStartDate(startDate);
        contractInfo.setEndDate(transformDate(vo.getRenewEndDate()));
        contractInfo.setTellerNo(vo.getTellerNo());
        contractInfo.setUserNo(vo.getUserNo());
        contractInfo.setCreateTime(new Date());
        //是否有效 1-有效 2无效
        contractInfo.setIsEffective("1");
        String forOperationStartDate = transformLocalTimeFormat(startDate);
        contractInfo.setOperationRecord(getUser().getUserName() + " 续签合同信息为 【" + forOperationStartDate + "~" + vo.getRenewEndDate() + "】");

        ylContractInfoMapper.insert(contractInfo);
        return ResultUtil.success();
    }


    /**
     * 检查护理等级记录  is_effective 1-有效 2-无效
     * 有效记录只能为一条
     *
     * @param userNo userNo
     */
    private void checkOnlyOneNursingRecord(String userNo) {
        QueryWrapper<YlNursingRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", "1");
        queryWrapper.orderByDesc("CREATE_TIME");
        List<YlNursingRecord> ylBedRecords = ylNursingRecordMapper.selectList(queryWrapper);
        if (ylBedRecords.size() > 1) {
            Integer recordNo = ylBedRecords.get(0).getNursingNo();
            ylBedRecords.forEach(model -> {
                if (!recordNo.equals(model.getNursingNo())) {
                    model.setIsEffective("2");
                    ylNursingRecordMapper.updateById(model);
                }
            });
        }
    }


    /**
     * 检查长护险记录集  is_effective 1-有效 2-无效
     * 有效记录只能为一条
     *
     * @param userNo userNo
     */
    private void checkOnlyOneAssessmentRecord(String userNo) {
        QueryWrapper<YlAssessmentRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", "1");
        queryWrapper.orderByDesc("CREATE_TIME");
        List<YlAssessmentRecord> ylBedRecords = ylAssessmentRecordMapper.selectList(queryWrapper);
        if (ylBedRecords.size() > 1) {
            Integer recordNo = ylBedRecords.get(0).getAssessmentNo();
            ylBedRecords.forEach(model -> {
                if (!recordNo.equals(model.getAssessmentNo())) {
                    model.setIsEffective("2");
                    ylAssessmentRecordMapper.updateById(model);
                }
            });
        }
    }


    /**
     * 修改 老人 房间信息
     *
     * @param vo vo
     * @return Result
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Object> updateYlElderlyInfoBuildingRoomBed(ElderlyInfoUpdateBuildingRoomBedVO vo) {
        if (Util.isNull(vo.getUserNo())) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }

        String nowTime = getNowTime();

        //获取有效的记录    (isEffective-是否有效 1-有效 2-无效 3-预订)
        YlBedRecord oldBedRecord = getYlBedRecordByUserNo(vo.getUserNo(), "1", null);

        //如果选择的时间小于等于当前时间  立刻生效
        if (Integer.parseInt(transformDate(vo.getEffectDate())) <= Integer.parseInt(nowTime)) {
            //新的  直接生效记录
            YlBedRecord bedRecord = getYlBedRecordForUpdateBedInfo(vo, oldBedRecord, "1");
            ylBedRecordMapper.insert(bedRecord);
            //修改老的
            oldBedRecord.setIsEffective("2");
            ylBedRecordMapper.updateById(oldBedRecord);

            //**********设置床位*************
            //之前有效的  老的床位  设置成空置的床
            setBedNoForBedEmpty(oldBedRecord.getBedNo(), "0");
            //新的床位  设置成已使用的床
            setBedNoForBedEmpty(bedRecord.getBedNo(), "1");
        }

        //如果选择的时间大于当前时间  记录为预定记录
        if (Integer.parseInt(transformDate(vo.getEffectDate())) > Integer.parseInt(nowTime)) {
            //新的
            YlBedRecord bedRecord = getYlBedRecordForUpdateBedInfo(vo, oldBedRecord, "3");

            //判断是否存在  isEffective=3的记录 有的话覆盖
            YlBedRecord isExistEffect = getYlBedRecordByUserNo(vo.getUserNo(), "3", null);
            if (Util.isNull(isExistEffect)) {
                ylBedRecordMapper.insert(bedRecord);
            } else {
                bedRecord.setRecordNo(isExistEffect.getRecordNo());
                ylBedRecordMapper.updateById(bedRecord);
            }
            //**********设置床位*************
            //新的床位  设置成已使用的床
            setBedNoForBedEmpty(bedRecord.getBedNo(), "2");
        }

        //检车床位记录 有效记录只能为一条  is_effective 1-有效 2-无效
//        checkOnlyOneBedRecord(vo.getUserNo());

        return ResultUtil.success();
    }


    /**
     * 获取床位记录 根据userNo 和 isEffective       有效记录和预定记录只会出现一条
     *
     * @param isEffective isEffective 是否有效 1-有效 2-无效 3-预订
     * @param effectDate  effectDate 生效日期
     * @param userNo      user
     * @return YlBedRecord
     */
    private YlBedRecord getYlBedRecordByUserNo(String userNo, String isEffective, String effectDate) {
        QueryWrapper<YlBedRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.eq("is_effective", isEffective);
        if (Util.isNotNull(effectDate)) {
            queryWrapper.eq("EFFECT_DATE", effectDate);
        }
        return ylBedRecordMapper.selectOne(queryWrapper);
    }

    /**
     * @param vo           vo
     * @param oldBedRecord oldBedRecord
     * @param isEffective  是否有效 1-有效 2-无效 3-预订
     * @return YlBedRecord
     */
    private YlBedRecord getYlBedRecordForUpdateBedInfo(ElderlyInfoUpdateBuildingRoomBedVO vo, YlBedRecord oldBedRecord, String isEffective) {
        YlBedRecord bedRecord = new YlBedRecord();
        bedRecord.setHistoryNo(String.valueOf(oldBedRecord.getRecordNo()));
        BeanUtils.copyProperties(vo, bedRecord);
        bedRecord.setEffectDate(transformDate(vo.getEffectDate()));
        bedRecord.setIsEffective(Util.isNull(isEffective) ? "1" : isEffective);
        bedRecord.setPensionNo(vo.getPensionNo());
        bedRecord.setUserNo(vo.getUserNo());
        bedRecord.setTellerNo(vo.getTellerNo());
        bedRecord.setCreateTime(new Date());
        String newMessage = getBedRecordOperationStr(bedRecord);
        String oldMessage = getBedRecordOperationStr(oldBedRecord);
        bedRecord.setOperationRecord(getUser().getUserName() + " 修改 床位信息" + oldMessage + " 为 " + newMessage);

        return bedRecord;
    }


    /**
     * 修改 老人 护理等级
     *
     * @param nursingRecord nursingRecord
     * @return Result
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Object> updateYlElderlyInfoNursing(YlNursingRecord nursingRecord) {
        if (Util.isNull(nursingRecord.getUserNo())) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }

        YlNursingRecord oldNursingRecord = getYlNursingRecord(nursingRecord.getUserNo());
        oldNursingRecord.setIsEffective("2");
        String oldMessage = getNursingOperationStr(oldNursingRecord);

        //--护理等级--
        //转换数据
        transformYlNursingRecord(nursingRecord);
        //是否有效 1-有效 2-无效
        nursingRecord.setIsEffective("1");
        nursingRecord.setCreateTime(new Date());
        String newMessage = getNursingOperationStr(nursingRecord);
        nursingRecord.setOperationRecord(getUser().getUserName() + " 修改 护理等级" + oldMessage + " 为 " + newMessage);
        ylNursingRecordMapper.insert(nursingRecord);
        //修改老的
        ylNursingRecordMapper.updateById(oldNursingRecord);

        //有效记录只能为一条  is_effective 1-有效 2-无效
        checkOnlyOneNursingRecord(nursingRecord.getUserNo());
        return ResultUtil.success();
    }

    /**
     * 修改 老人 长护险
     *
     * @param assessmentRecord assessmentRecord
     * @return Result
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Object> updateYlElderlyInfoAssessment(YlAssessmentRecord assessmentRecord) {
        if (Util.isNull(assessmentRecord.getUserNo())) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }

        YlAssessmentRecord oldRecord = getYlAssessmentRecord(assessmentRecord.getUserNo());
        oldRecord.setIsEffective("2");
        String oldMessage = getAssessmentOperationStr(oldRecord);


        //评估等级
        transformYlAssessmentRecord(assessmentRecord);
        assessmentRecord.setIsEffective("1");
        assessmentRecord.setCreateTime(new Date());
        String newMessage = getAssessmentOperationStr(assessmentRecord);
        assessmentRecord.setOperationRecord(getUser().getUserName() + " 修改 评估信息" + oldMessage + " 为 " + newMessage);
        //类型 1-基础数据 2-健康档案
        assessmentRecord.setRecordType("1");
        ylAssessmentRecordMapper.insert(assessmentRecord);
        //修改老的
        ylAssessmentRecordMapper.updateById(oldRecord);

        //检查长护险记录集 有效的是否只有一条
        checkOnlyOneAssessmentRecord(assessmentRecord.getUserNo());
        return ResultUtil.success();
    }

    /**
     * 老人 退住
     *
     * @param ylElderlyInfo ylElderlyInfo
     * @return Result
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Object> updateElderlyForIsStayBack(YlElderlyInfo ylElderlyInfo) {
        YlElderlyInfo info = ylElderlyInfoMapper.selectById(ylElderlyInfo.getUserNo());
        if (Util.isNull(ylElderlyInfo.getUserNo()) || Util.isNull(info)) {
            return ResultUtil.errorMsg("无法查询到此老人信息");
        }

        //**********办理退住时，判断是否欠费，如果欠费无法办理退住*******************
        YlElderlyBill elderlyBill = ylElderlyBillMapper.selectById(info.getUserNo());
        if (Util.isNotNull(elderlyBill)) {
            //缴费状态 0-结清 1-余额 2-欠费
            if ("2".equals(elderlyBill.getBillState())) {
                return ResultUtil.errorMsg("该老人有欠费信息,无法办理退住");
            }
        }

        //退住时间
        if (Util.isNotNull(ylElderlyInfo.getStayBackDate())) {
            info.setStayBackDate(transformDate(ylElderlyInfo.getStayBackDate()));
        }
        //退住理由
        if (Util.isNotNull(ylElderlyInfo.getStayBackReason())) {
            info.setStayBackReason(ylElderlyInfo.getStayBackReason());
        }
        //死亡日期
        if (Util.isNotNull(ylElderlyInfo.getDeathDate())) {
            info.setDeathDate(transformDate(ylElderlyInfo.getDeathDate()));
        }

        //是否退住 1-否 2-是
        info.setIsStayBack(2);
        //1正常 9：删除 8:退住
        info.setUserState("8");
        ylElderlyInfoMapper.updateById(info);

        //*********房间置空 ******************
        // 有效的和已预订的
        YlBedRecord ylBedRecordOne = getYlBedRecordByUserNo(ylElderlyInfo.getUserNo(), "1", null);
        if (Util.isNotNull(ylBedRecordOne)) {
            setBedNoForBedEmpty(ylBedRecordOne.getBedNo(), "0");
        }
        YlBedRecord ylBedRecordThree = getYlBedRecordByUserNo(ylElderlyInfo.getUserNo(), "3", null);
        if (Util.isNotNull(ylBedRecordThree)) {
            setBedNoForBedEmpty(ylBedRecordThree.getBedNo(), "0");
        }
        return ResultUtil.success();
    }


    /**
     * date -> yyyy-MM-dd HH:mm:ss
     *
     * @param date date
     * @return String
     */
    private String getFormatDateTime(Date date) {
        if (Util.isNull(date)) {
            return "";
        }
        return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
    }

    /**
     * 获取入驻合同 历史记录
     *
     * @param userNo userNo
     * @return Result
     */
    @Override
    public Result<Object> getHistoryContractList(String userNo) {

        QueryWrapper<YlContractInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByAsc("CREATE_TIME");
        //获取合同列表 列表 根据创建时间正序
        List<YlContractInfo> ylContractInfos = ylContractInfoMapper.selectList(queryWrapper);

        ylContractInfos.forEach(model -> {
            if (Util.isNotNull(model.getCreateTime())) {
                model.setFormatCreateTime(getFormatDateTime(model.getCreateTime()));
            }
        });
        return ResultUtil.getDataSuccess(ylContractInfos);
    }

    private String getNowTime() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    }


    /**
     * 获取床位记录  历史记录
     *
     * @param userNo userNo
     * @return Result
     */
    @Override
    public Result<Object> getHistoryBedRecordList(String userNo) {

        QueryWrapper<YlBedRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByAsc("CREATE_TIME");
        //获取合同列表 列表 根据创建时间正序
        List<YlBedRecord> bedRecords = ylBedRecordMapper.selectList(queryWrapper);

        bedRecords.forEach(model -> {
            if (Util.isNotNull(model.getCreateTime())) {
                model.setFormatCreateTime(getFormatDateTime(model.getCreateTime()));
            }
            //1-已生效 2-未生效
            if (Util.isNotNull(model.getIsEffective())) {
                model.setIsEffect(model.getIsEffective());
            } else {
                model.setIsEffect("2");
            }
//            //1-已生效 2-未生效   生效规则：当前实时时间>=生效时间，则显示已生效；当前实时时间<生效时间，则显示未生效；
//            if (Integer.parseInt(nowTime) >= Integer.parseInt(model.getEffectDate())) {
//                model.setIsEffect("1");
//            } else if (Integer.parseInt(nowTime) < Integer.parseInt(model.getEffectDate())) {
//                model.setIsEffect("2");
//            }
        });

        return ResultUtil.getDataSuccess(bedRecords);
    }

    /**
     * 获取护理等级记录 历史
     *
     * @param userNo userNo
     * @return Result
     */
    @Override
    public Result<Object> getHistoryNursingRecordList(String userNo) {

        String nowTime = getNowTime();

        QueryWrapper<YlNursingRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByAsc("CREATE_TIME");
        //获取合同列表 列表 根据创建时间正序
        List<YlNursingRecord> nursingRecords = ylNursingRecordMapper.selectList(queryWrapper);
        nursingRecords.forEach(model -> {
            //生效规则：当前实时时间>=生效时间，则显示已生效；当前实时时间<生效时间，则显示未生效
            //1-已生效 2-未生效
            if (Integer.parseInt(nowTime) >= Integer.parseInt(model.getEffectDate())) {
                model.setIsEffect("1");
            } else if (Integer.parseInt(nowTime) < Integer.parseInt(model.getEffectDate())) {
                model.setIsEffect("2");
            }
            if (Util.isNotNull(model.getCreateTime())) {
                model.setFormatCreateTime(getFormatDateTime(model.getCreateTime()));
            }
        });

        return ResultUtil.getDataSuccess(nursingRecords);
    }

    /**
     * 获取 评估等级 历史记录
     *
     * @param userNo userNo
     * @return Result
     */
    @Override
    public Result<Object> getHistoryAssessmentRecordList(String userNo) {
        String nowTime = getNowTime();

        QueryWrapper<YlAssessmentRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByAsc("CREATE_TIME");
        //获取合同列表 列表 根据创建时间正序
        List<YlAssessmentRecord> assessmentRecords = ylAssessmentRecordMapper.selectList(queryWrapper);
        assessmentRecords.forEach(model -> {

            //生效规则：当前实时时间>=生效时间，则显示已生效；当前实时时间<生效时间，则显示未生效
            //1-已生效 2-未生效
            if (Integer.parseInt(nowTime) >= Integer.parseInt(model.getEffectDate())) {
                model.setIsEffect("1");
            } else if (Integer.parseInt(nowTime) < Integer.parseInt(model.getEffectDate())) {
                model.setIsEffect("2");
            }
            //生效时间
            if (Util.isNotNull(model.getEffectDate())) {
                model.setEffectDate(transformLocalTimeFormat(model.getEffectDate()));
            }
            if (Util.isNotNull(model.getCreateTime())) {
                model.setFormatCreateTime(getFormatDateTime(model.getCreateTime()));
            }
        });
        return ResultUtil.getDataSuccess(assessmentRecords);
    }


    /**
     * 获取 YlCost
     *
     * @param costNo costNo
     * @return Result
     */
    @Override
    public Result<Object> getCost(String costNo) {
        if (Util.isNull(costNo)) {
            ResultUtil.errorMsg("获取护理等级图片失败");
        }
        return ResultUtil.getDataSuccess(getYlCostByCostNo(costNo));
    }


    /**
     * 计算是否生效 通过生效时间   ---床位记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateBedRecordByEffectDate(String userNo) {

        String nowTime = getNowTime();
        //获取有效日期 为当前时间的
        YlBedRecord ylBedRecord = getYlBedRecordByUserNo(userNo, "3", nowTime);
        if (Util.isNull(ylBedRecord)) {
            return;
        }

        //查出有效记录
        YlBedRecord oldYlBedRecord = getYlBedRecordByUserNo(userNo, "1", null);
        //如果生效日期为当前的记录存在  老的有效记录改成无效
        oldYlBedRecord.setIsEffective("2");
        ylBedRecordMapper.updateById(oldYlBedRecord);

        //isEffective 是否有效 1-有效 2-无效 3-预订
        //当前生效日期的记录存在 改为 有效状态
        ylBedRecord.setIsEffective("1");
        ylBedRecordMapper.updateById(ylBedRecord);
    }


    /**
     * 计算是否生效 通过生效时间   --- 护理记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateNursingRecordByEffectDate(String userNo) {
        String nowTime = getNowTime();
        QueryWrapper<YlNursingRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByDesc("EFFECT_DATE", "CREATE_TIME");
        //床位时间
        List<YlNursingRecord> nursingRecords = ylNursingRecordMapper.selectList(queryWrapper);

        //判断是否有今日的生效记录  只需要一条   时间最靠近的现在的
        Optional<YlNursingRecord> optional = nursingRecords.stream().filter(nursingRecord -> {
            //1-已生效 2-未生效   生效规则：当前实时时间>=生效时间，则显示已生效；当前实时时间<生效时间，则显示未生效；
            return Integer.parseInt(nowTime) >= Integer.parseInt(nursingRecord.getEffectDate());
        }).findFirst();

        //不存在 直接跳出
        if (!optional.isPresent()) {
            return;
        }

        YlNursingRecord realTrueRecord = optional.get();
        //去除有效的记录 其他IsEffective 全变无效
        nursingRecords.remove(realTrueRecord);
        nursingRecords.forEach(model -> {
            //IsEffective 1-有效 2-无效
            model.setIsEffective("2");
            ylNursingRecordMapper.updateById(model);
        });

        //记录有效的记录
        realTrueRecord.setIsEffective("1");
        ylNursingRecordMapper.updateById(realTrueRecord);
    }


    /**
     * 计算是否生效 通过生效时间   --- 评估记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateAssessmentRecordByEffectDate(String userNo) {
        String nowTime = getNowTime();
        QueryWrapper<YlAssessmentRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NO", userNo);
        queryWrapper.orderByDesc("EFFECT_DATE", "CREATE_TIME");
        //床位时间
        List<YlAssessmentRecord> assessmentRecords = ylAssessmentRecordMapper.selectList(queryWrapper);

        //判断是否有今日的生效记录  只需要一条   时间最靠近的现在的
        Optional<YlAssessmentRecord> optional = assessmentRecords.stream().filter(assessmentRecord -> {
            //1-已生效 2-未生效   生效规则：当前实时时间>=生效时间，则显示已生效；当前实时时间<生效时间，则显示未生效；
            return Integer.parseInt(nowTime) >= Integer.parseInt(assessmentRecord.getEffectDate());
        }).findFirst();

        //不存在 直接跳出
        if (!optional.isPresent()) {
            return;
        }

        YlAssessmentRecord realTrueRecord = optional.get();
        //去除有效的记录 其他IsEffective 全变无效
        assessmentRecords.remove(realTrueRecord);
        assessmentRecords.forEach(model -> {
            //IsEffective 1-有效 2-无效
            model.setIsEffective("2");
            ylAssessmentRecordMapper.updateById(model);
        });

        //记录有效的记录
        realTrueRecord.setIsEffective("1");
        ylAssessmentRecordMapper.updateById(realTrueRecord);
    }

}
